<?php

declare(strict_types=1);

namespace App\Model\Service;

use App\Event\RechargeEvent;
use App\Helpers\ConfigUtil;
use App\Model\CoinLog;
use App\Model\Message;
use App\Model\PayOrder;
use App\Model\UserCoin;
use Hyperf\DbConnection\Db;
use Psr\EventDispatcher\EventDispatcherInterface;

/**
 *  支付回调模型
 */
class PaycallbackService
{
    /**
     * 支付成功回调
     */
    static function successCallback($outTradeNo = '', $payMoney = 0, $channel = '')
    {
        if (!$outTradeNo) return;
        $logKey = "{$outTradeNo}=={$channel}=={$payMoney}";
        $record = PayOrder::getByOutTradeNo($outTradeNo);
        //没有记录
        if (!$record) {
            log_info(__CLASS__ . "==NoRecord=={$logKey}");
            return;
        }
//return time() - strtotime((string)$record['created_at']);
        if (($passTime = time() - strtotime((string)$record['created_at'])) > 1800) {
            log_info(__CLASS__ . "==OrderOverTime=={$logKey}==PassTime:{$passTime}");
            return;
        }

        // $record = $record->toArray();
        //当前状态是否已处理
        if ($record['status'] != PayOrder::STATUS_ING) {
            log_info(__CLASS__ . "==OrderProcessed=={$logKey}");
            return;
        }

        //回调信息与订单信息不匹配
        // log_info(__CLASS__ . "=={$record['total_amount']}=={$payMoney}####{$record['channel']}=={$channel}");
        if ($record['total_amount'] != $payMoney || $record['channel'] != $channel) {
            log_info(__CLASS__ . "==InfoNotRight=={$logKey}");
            return;
        }

        Db::beginTransaction();
        try {
            //是否首充
            $firstPay = PayOrder::checkSuccess($record['user_id']) ? false : true;
            //更新虚拟账户
            $coinConf = ConfigUtil::getRecharge($record['subject_id'], $record['channel'], true, $firstPay);
            //充值金币加额外金币（赠送，活动等）
            $gainCoin = $coinConf['coin'];
            $remainCoin = UserCoin::gainRecharge($record['user_id'], $gainCoin);
            //添加流水记录
            CoinLog::addReCharge(
                $record['user_id'],
                $gainCoin,
                $record['order_id'],
                $remainCoin,
                CoinLog::FROM_RECHARGE
            );

            //更新订单状态
            PayOrder::updateSuccess($record['id']);

            //额外赠送
            $extraCoin = self::extraCoin($coinConf);
            if ($extraCoin > 0) {
                $remainCoin = UserCoin::gainRecharge($record['user_id'], $extraCoin);
                //添加流水记录
                CoinLog::addReCharge(
                    $record['user_id'],
                    $extraCoin,
                    $record['order_id'],
                    $remainCoin,
                    CoinLog::FROM_RECHARGE_SEND
                );
            }
            log_info(__CLASS__ . "==AllDone=={$logKey}");
            Db::commit();
        } catch (\Throwable $exception) {
            log_info(__CLASS__ . "==Exception:" . $exception->getMessage());
            Db::rollBack();
	}

        //充值事件触发
        make(EventDispatcherInterface::class)->dispatch(new RechargeEvent(
            $record['user_id'],
            $coinConf['coin'],
            $record['total_amount'] / 100,
            $record['order_id']
        ));
        //透传-账户余额变动
        Message::sendSlient($record['user_id'], 'USER_COIN_CHANGE', ['from' => 'recharge']);
    }

    /**
     * 获取当前订单额外赠送的金币数（活动赠送之类的）
     */
    static function extraCoin($coinConf = [])
    {
        return $coinConf['send'] ?? 0;
    }
}
